/**
 * @export
 * @class Building
 * @classdesc 楼/楼层对象
 * @property {Object} 地图容器 - SchoolLab实例
 * @property {String} name - 名称
 * @property {String} color - 颜色
 * @property {Number} opacity - 透明度
 * @property {Number} radius - 半径
 * @property {Number} renderOrder - 层叠顺序
 * @property {Number} bevelThickness - 边缘倒角
 * @property {Number} floor - 楼层数
 * @property {Object} userData - 用于存放私有数据
 * @property {Function} click - 点击事件回调
 * @property {Function} hover - hover事件回调
 * @property {Array} path - 轮廓点集
 * @example
 * var building = new Building(viewer, {
 *   floor: 4,
 *   color: '#ff0000',
 *   opacity: 0.5,
 *   renderOrder: 20,
 *   name: 'building',
 *   path: [],
 *   click: function() {},
 *   hover: function() {},
 *   userData: {}
 * })
 */
import { extend } from './util'
import { ELEVATION } from './Constant'
import Feature from './Feature'
export default class Building {
  constructor(viewer, options) {
    const opts = extend({
      name: "building",
      color: "#172437",
      opacity: 1,
      renderOrder: 1,
      bevelThickness: 0,
      floor: 1,
      userData: null,
      click: null,
      hover: null
    }, options)

    /** @member {SchoolLab} - 地图容器 */
    this.viewer = viewer

    /** @member {String} - 名称 */
    this.name = opts.name
    
    /** @member {Color} - 颜色 */
    this.color = opts.color
    
    /** @member {Number} - 透明度 */
    this.opacity = opts.opacity
    
    /** @member {Number} - 层叠顺序 */
    this.renderOrder = opts.renderOrder
    
    /** @member {Number} - 边缘倒角 */
    this.bevelThickness = opts.bevelThickness
    
    /** @member {Object} - 私有数据存储 */
    this.userData = opts.userData
    
    /** @member {Array} - 轮廓点集 */
    this.path = opts.path
    
    /** @member {Number} - 楼层数 */
    this.floor = opts.floor
    
    /** @member {THREE.Mesh} - mesh对象 */
    this.entity = null
    
    /** @member {THREE.LineSegments} - 外轮廓line对象 */
    this.outlineEntity = null
    
    /** @member {Function} - 点击回调 */
    this.click = opts.click
    
    /** @member {Function} - hover回调 */
    this.hover = opts.hover

    
    /** @member {Object} - 各种状态样式配置 */
    this.colors = {
      'normal': this.color,
      'orange': '#F3732F',
      'yellow': '#F6D501',
      'red': '#F63253'
    }

    /** @member {String} - 当前所处状态 */
    this.status = 'normal'

    Feature.apply(this)

    this._init()
  }

  _init() {
    let geometry = this._initGeometry()
    let material = this._initMaterial()
    
    const mesh = new THREE.Mesh(geometry, material)
    mesh.name = this.name
    mesh.renderOrder = this.renderOrder
    mesh.ctx = this
    if (this.userData) mesh.userData = this.userData
    if (this.click) mesh.click = this.click
    if (this.hover) mesh.hover = this.hover
    
    this.entity = mesh
    this.viewer.world.add(mesh)

    const outline = new THREE.LineSegments(geometry, new THREE.MeshStandardMaterial({
      color: new THREE.Color("#27C0ED"),
      transparent: true,
      depthTest: true,
      depthWrite: false,
      side: THREE.DoubleSide,
      blending: THREE.AdditiveBlending,
      opacity: 0.6
    }))
    outline.name = this.name
    outline.renderOrder = this.renderOrder + 1
    outline.visible = false
    this.outlineEntity = outline
    this.viewer.world.add(outline)
  }

  // 初始化几何体
  _initGeometry() {
    let shape = new THREE.Shape(this.path)
    let geometry = new THREE.ExtrudeBufferGeometry(shape, {
      depth: ELEVATION * this.floor,
      steps: 1,
      bevelEnabled: true,
      bevelThickness: this.bevelThickness,
      bevelSize: 0.5,
      bevelOffset: 0,
      bevelSegments: 1
    })
    return geometry
  }

  // 初始化材质
  _initMaterial() {
    const material = new THREE.MeshPhongMaterial({
      color: new THREE.Color(this.color),
      // depthWrite: false,
      depthTest: true,
      transparent: true,
      side: THREE.FrontSide,
      blending: THREE.NormalBlending,
      opacity: this.opacity
    })

    return material
  }

  // 选中当前对象
  choose() {
    let color = this.colors[this.status]
    this.entity.material.color = new THREE.Color(color)
    this.entity.material.blending = THREE.AdditiveBlending
    this.entity.material.opacity = 0.75

    this.outlineEntity.material.color = new THREE.Color(color)
    this.outlineEntity.visible = true
  }

  // 取消选中当前对象
  unChoose() {
    this.entity.material.color = new THREE.Color(this.colors[this.status])
    this.entity.material.blending = THREE.NormalBlending
    this.entity.material.opacity = this.opacity

    this.outlineEntity.material.color = new THREE.Color('#27C0ED')
    this.outlineEntity.visible = false
  }

  // 设置当前对象的状态
  setStatus(status) {
    if (this.status === status) return
    this.entity.material.color = new THREE.Color(this.colors[status])
    this.status = status
  }

  // 销毁楼/楼层对象
  destroy() {
    this._disposeHierarchy(this.entity, this._dispose)
    this.viewer.world.remove(this.entity)
    this.entity = null
    
    this._disposeHierarchy(this.outlineEntity, this._dispose)
    this.viewer.world.remove(this.outlineEntity)
    this.outlineEntity = null
  }
}
